/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2010, LABUST, UNIZG-FER
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the LABUST nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*
*  Author : Dula Nad
*  Created: 31.01.2013.
*********************************************************************/
#ifndef SENSORINTERFACE_HPP_
#define SENSORINTERFACE_HPP_

#include <boost/shared_ptr.hpp>
#include <osg/ref_ptr>
#include <ros/ros.h>
#include <libxml++/libxml++.h>

#include <string>
#include <list>

class ROSInterface;
class osgOceanScene;
class ROSInterfaceInfo;
class URDFRobot;

namespace osg
{
class Transform;
class Group;
}

namespace xmlpp
{
	class Node;
}

namespace plugin
{
	/**
	 * It seems to me that many sensors require different elements from the OSG scene and similar.
	 * So lets make a generic hook file that can be used for passing that stuff to sensors. Those
	 * that need it can use it, others don't have to.
	 */
	struct UWSimHook
	{
		typedef boost::shared_ptr<UWSimHook> Ptr;
		osg::ref_ptr<osgOceanScene> scene;
		osg::ref_ptr<osg::Transform> vMs;
		osg::ref_ptr<osg::Group> root;
		boost::shared_ptr<URDFRobot> urdf;
	};

	/**
	 * For backward compatibility we export a part of XML configuration. Alternatively, a parent URDF object could be passed.
	 */
	struct SensorXML
	{
		typedef boost::shared_ptr<SensorXML> Ptr;

		/**
		 * Generic init.
		 */
		SensorXML():
			name(""),
			linkName("")
		{
			position[0]=0;position[1]=0;position[2]=0;orientation[0]=0;orientation[1]=0;orientation[2]=0;
		}

		std::string name, linkName;
	  double position[3],orientation[3];
	  int link;
	};

	class ROSInterfaceFactory
	{
	public:
		typedef boost::shared_ptr<ROSInterfaceFactory> Ptr;
		typedef boost::shared_ptr<ROSInterface> ROSInterfacePtr;
		ROSInterfaceFactory(){};
		virtual ~ROSInterfaceFactory(){};
		/**
		 * Get the XML configuration ROS node name. Needed for compatibility.
		 */
		virtual std::string getRosInterfaceXmlName() = 0;
		/**
		 * The ROSInterface factory. Returns a configured ROS Interface.
		 */
		virtual ROSInterfacePtr createRosInterface(ros::NodeHandle, ROSInterfaceInfo*, UWSimHook::Ptr) = 0;
	};
	/**
	 * A generic sensor interface. Includes the ROSInterface, main sensor body, etc. needed to generically a simple
	 * sensor into UWSim.
	 */
	class SensorInterface : public virtual ROSInterfaceFactory
	{
	public:
		typedef boost::shared_ptr<SensorInterface> Ptr;
		/**
		 * The generic constructor.
		 */
		SensorInterface(){};
		/**
		 * Generic virtual destructor.
		 */
		virtual ~SensorInterface(){};

		/**
		 * Create the sensor.
		 * \todo add return value when it goes to factory.
		 */
		virtual void createSensor(UWSimHook::Ptr hook) = 0;
		/**
		 * Get the XML configuration name of the sensor. Needed for compatibility.
		 */
		virtual std::string getSensorXmlName() = 0;
		/**
		 * Get the internal scene name of the sensor. Needed for compatibility.
		 */
		virtual std::string getSensorSceneName() = 0;

		/**
		 * Get generic XML format.
		 */
		virtual SensorXML::Ptr getGenericSensorXML() = 0;

		/**
		 * Set generic XML format.
		 */
		virtual void setGenericSensorXML(SensorXML::Ptr) = 0;

		/**
		 * Configure the sensor using the XML node.
		 */
		virtual void configureSensor(const xmlpp::Node* node) = 0;
	};

	typedef std::list<SensorInterface::Ptr> SensorList;
	typedef std::list<ROSInterfaceFactory::Ptr> ROSInterfaceList;
}


/* SENSORINTERFACE_HPP_ */
#endif
